home *** CD-ROM | disk | FTP | other *** search
- /* $Id: osmesa.c,v 1.5 1995/11/03 17:40:00 brianp Exp $ */
-
- /*
- * Mesa 3-D graphics library
- * Version: 1.2
- * Copyright (C) 1995 Brian Paul (brianp@ssec.wisc.edu)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- $Log: osmesa.c,v $
- * Revision 1.5 1995/11/03 17:40:00 brianp
- * added casts for C++ compilation
- *
- * Revision 1.4 1995/10/30 15:32:58 brianp
- * added mask argument to read_[color|index]_pixels functions
- *
- * Revision 1.3 1995/10/19 15:49:06 brianp
- * changed clear_color and set_color arguments to GLubytes
- * changed arguments to gl_new_context
- *
- * Revision 1.2 1995/10/13 22:41:58 brianp
- * renamed index to set_index and color to set_color
- * make index_mask and color_mask return GL_FALSE
- *
- * Revision 1.1 1995/10/12 17:00:03 brianp
- * Initial revision
- *
- */
-
-
-
- /*
- * Off-Screen Mesa rendering / Rendering into client memory space
- */
-
-
- #include <stdlib.h>
- #include <string.h>
- #include "GL/osmesa.h"
- #include "context.h"
- #include "dd.h"
- #include "macros.h"
- #include "xform.h"
-
-
- struct osmesa_context {
- struct gl_context *gl_ctx; /* The GL/Mesa context */
- GLenum format; /* either GL_RGBA or GL_COLOR_INDEX */
- void *buffer; /* the image buffer */
- GLint width, height; /* size of image buffer */
- GLuint pixel; /* current color index or RGBA pixel value */
- GLuint clearpixel; /* pixel for clearing the color buffer */
- };
-
-
-
- static OSMesaContext Current = NULL;
-
- static void setup_DD_pointers( void );
-
-
-
- /*
- * Create an Off-Screen Mesa rendering context. The only attribute needed is
- * an RGBA vs Color-Index mode flag.
- *
- * Input: format - either GL_RGBA or GL_COLOR_INDEX
- * sharelist - specifies another OSMesaContext with which to share
- * display lists. NULL indicates no sharing.
- * Return: an OSMesaContext or 0 if error
- */
- OSMesaContext OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
- {
- OSMesaContext ctx;
-
- if (format!=GL_RGBA && format!=GL_COLOR_INDEX) {
- return NULL;
- }
-
- ctx = (OSMesaContext) malloc( sizeof(struct osmesa_context) );
- if (ctx) {
- ctx->gl_ctx = gl_new_context( (format==GL_RGBA) ? GL_TRUE : GL_FALSE,
- 255.0, 255.0, 255.0, 255.0,
- GL_FALSE,
- sharelist ? sharelist->gl_ctx : NULL );
- if (!ctx->gl_ctx) {
- free(ctx);
- return NULL;
- }
- #ifdef FOO
- ctx->gl_ctx->RGBAflag = (format==GL_RGBA);
- ctx->gl_ctx->RedScale = 255.0;
- ctx->gl_ctx->GreenScale = 255.0;
- ctx->gl_ctx->BlueScale = 255.0;
- ctx->gl_ctx->AlphaScale = 255.0;
- ctx->gl_ctx->Color.DrawBuffer = GL_FRONT;
- ctx->gl_ctx->Pixel.ReadBuffer = GL_FRONT;
- #endif
- ctx->format = format;
- ctx->buffer = NULL;
- ctx->width = 0;
- ctx->height = 0;
- ctx->pixel = 0;
- ctx->clearpixel = 0;
- }
- return ctx;
- }
-
-
-
- /*
- * Destroy an Off-Screen Mesa rendering context.
- *
- * Input: ctx - the context to destroy
- */
- void OSMesaDestroyContext( OSMesaContext ctx )
- {
- if (ctx) {
- gl_destroy_context( ctx->gl_ctx );
- free( ctx );
- }
- }
-
-
-
- /*
- * Bind an OSMesaContext to an image buffer. The image buffer is just a
- * block of memory which the client provides. Its size must be at least
- * as large as width*height*sizeof(type). Its address should be a multiple
- * of 4 if using RGBA mode.
- *
- * Image data is stored in the order of glDrawPixels: row-major order
- * with the lower-left image pixel stored in the first array position
- * (ie. bottom-to-top).
- *
- * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
- * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
- * value. If the context is in color indexed mode, each pixel will be
- * stored as a 1-byte value.
- *
- * If the context's viewport hasn't been initialized yet, it will now be
- * initialized to (0,0,width,height).
- *
- * Input: ctx - the rendering context
- * buffer - the image buffer memory
- * type - data type for pixel components, only GL_UNSIGNED_BYTE
- * supported now
- * width, height - size of image buffer in pixels, at least 1
- * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
- * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
- * width>internal limit or height>internal limit.
- */
- GLboolean OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
- GLsizei width, GLsizei height )
- {
- if (!ctx || !buffer || type!=GL_UNSIGNED_BYTE
- || width<1 || height<1 || width>MAX_WIDTH || height>MAX_HEIGHT) {
- return GL_FALSE;
- }
-
- gl_set_context( ctx->gl_ctx );
-
- ctx->buffer = buffer;
- ctx->width = width;
- ctx->height = height;
-
- setup_DD_pointers();
-
- Current = ctx;
-
- /* init viewport */
- if (ctx->gl_ctx->Viewport.Width==0) {
- /* initialize viewport and scissor box to buffer size */
- gl_viewport( 0, 0, width, height );
- CC.Scissor.X = 0;
- CC.Scissor.Y = 0;
- CC.Scissor.Width = width;
- CC.Scissor.Height = height;
- }
-
- return GL_TRUE;
- }
-
-
-
-
- /**********************************************************************/
- /*** Device Driver Functions ***/
- /**********************************************************************/
-
-
- static void finish( void )
- {
- /*NOP*/
- }
-
-
-
- static void flush( void )
- {
- /*NOP*/
- }
-
-
-
- static GLboolean set_buffer( GLenum mode )
- {
- if (mode==GL_FRONT) {
- return GL_TRUE;
- }
- else {
- return GL_FALSE;
- }
- }
-
-
- static void clear_index( GLuint index )
- {
- Current->clearpixel = index;
- }
-
-
-
- static void clear_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
- {
- /* This trick facilitates big & little endian */
- GLubyte *clr = (GLubyte *) &Current->clearpixel;
- clr[0] = r;
- clr[1] = g;
- clr[2] = b;
- clr[3] = a;
- }
-
-
-
- static void clear( GLboolean all, GLint x, GLint y, GLint width, GLint height )
- {
- if (Current->format==GL_RGBA) {
- if (all) {
- /* Clear whole RGBA buffer */
- GLuint i, n, *ptr4;
- n = Current->width * Current->height;
- ptr4 = (GLuint *) Current->buffer;
- for (i=0;i<n;i++) {
- *ptr4++ = Current->clearpixel;
- }
- }
- else {
- /* Clear part of RGBA buffer */
- GLuint i, j;
- for (i=0;i<height;i++) {
- GLuint *ptr4 = (GLuint *) (Current->buffer) + Current->width * (y+i) + x;
- for (j=0;j<width;j++) {
- *ptr4++ = Current->clearpixel;
- }
- }
- }
- }
- else {
- if (all) {
- /* Clear whole CI buffer */
- MEMSET(Current->buffer, Current->clearpixel, Current->width*Current->height);
- }
- else {
- /* Clear part of CI buffer */
- GLuint i, j;
- for (i=0;i<height;i++) {
- GLubyte *ptr1 = (GLubyte *) (Current->buffer) + Current->width * (y+i) + x;
- for (j=0;j<width;j++) {
- *ptr1++ = Current->clearpixel;
- }
- }
- }
- }
- }
-
-
-
- static void set_index( GLuint index )
- {
- Current->pixel = index;
- }
-
-
-
- static GLboolean index_mask( GLuint mask )
- {
- return GL_FALSE;
- }
-
-
-
- static void set_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
- {
- /* This trick facilitates big & little endian */
- GLubyte *clr = (GLubyte *) &Current->pixel;
- clr[0] = r;
- clr[1] = g;
- clr[2] = b;
- clr[3] = a;
- }
-
-
- static GLboolean color_mask( GLboolean rmask, GLboolean gmask,
- GLboolean bmask, GLboolean amask )
- {
- return GL_FALSE;
- }
-
-
-
- static GLboolean logicop( GLenum mode )
- {
- if (mode==GL_COPY) {
- return GL_TRUE;
- }
- else {
- return GL_FALSE;
- }
- }
-
-
- static void dither( GLboolean enable )
- {
- /* NOP, never dither */
- }
-
-
- static void buffer_size( GLuint *width, GLuint *height, GLuint *depth )
- {
- *width = Current->width;
- *height = Current->height;
- *depth = 8;
- }
-
-
-
- /*
- * Useful macros:
- */
- #define OFFSET(X,Y) ((Y) * Current->width + (X))
- #define PACK_RGBA(R,G,B,A) (((R) << 24) | ((G) << 16) | ((B) << 8) | (A))
- #define PACK_ABGR(R,G,B,A) (((A) << 24) | ((B) << 16) | ((G) << 8) | (R))
-
-
-
-
- static void write_RGBA_span( GLuint n, GLint x, GLint y,
- const GLubyte red[], const GLubyte green[],
- const GLubyte blue[], const GLubyte alpha[],
- const GLubyte mask[] )
- {
- GLuint *ptr4 = (GLuint *) Current->buffer + OFFSET(x,y);
- GLuint i;
- if (mask) {
- for (i=0;i<n;i++,ptr4++) {
- if (mask[i]) {
- *ptr4 = PACK_RGBA( red[i], green[i], blue[i], alpha[i] );
- }
- }
- }
- else {
- for (i=0;i<n;i++,ptr4++) {
- *ptr4 = PACK_RGBA( red[i], green[i], blue[i], alpha[i] );
- }
- }
- }
-
-
-
- static void write_ABGR_span( GLuint n, GLint x, GLint y,
- const GLubyte red[], const GLubyte green[],
- const GLubyte blue[], const GLubyte alpha[],
- const GLubyte mask[] )
- {
- GLuint *ptr4 = (GLuint *) Current->buffer + OFFSET(x,y);
- GLuint i;
- if (mask) {
- for (i=0;i<n;i++,ptr4++) {
- if (mask[i]) {
- *ptr4 = PACK_ABGR( red[i], green[i], blue[i], alpha[i] );
- }
- }
- }
- else {
- for (i=0;i<n;i++,ptr4++) {
- *ptr4 = PACK_ABGR( red[i], green[i], blue[i], alpha[i] );
- }
- }
- }
-
-
-
- static void write_monocolor_span( GLuint n, GLint x, GLint y,
- const GLubyte mask[] )
- {
- GLuint *ptr4 = (GLuint *) Current->buffer + OFFSET(x,y);
- GLuint i;
- for (i=0;i<n;i++,ptr4++) {
- if (mask[i]) {
- *ptr4 = Current->pixel;
- }
- }
- }
-
-
-
- static void write_RGBA_pixels( GLuint n, const GLint x[], const GLint y[],
- const GLubyte red[], const GLubyte green[],
- const GLubyte blue[], const GLubyte alpha[],
- const GLubyte mask[] )
- {
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLuint *ptr4 = (GLuint *) Current->buffer + OFFSET(x[i],y[i]);
- *ptr4 = PACK_RGBA( red[i], green[i], blue[i], alpha[i] );
- }
- }
- }
-
-
-
- static void write_ABGR_pixels( GLuint n, const GLint x[], const GLint y[],
- const GLubyte red[], const GLubyte green[],
- const GLubyte blue[], const GLubyte alpha[],
- const GLubyte mask[] )
- {
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLuint *ptr4 = (GLuint *) Current->buffer + OFFSET(x[i],y[i]);
- *ptr4 = PACK_ABGR( red[i], green[i], blue[i], alpha[i] );
- }
- }
- }
-
-
-
- static void write_monocolor_pixels( GLuint n, const GLint x[], const GLint y[],
- const GLubyte mask[] )
- {
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLuint *ptr4 = (GLuint *) Current->buffer + OFFSET(x[i],y[i]);
- *ptr4 = Current->pixel;
- }
- }
- }
-
-
-
- static void write_index_span( GLuint n, GLint x, GLint y, const GLuint index[],
- const GLubyte mask[] )
- {
- GLubyte *ptr1 = (GLubyte *) Current->buffer + OFFSET(x,y);
- GLuint i;
- for (i=0;i<n;i++,ptr1++) {
- if (mask[i]) {
- *ptr1 = (GLubyte) index[i];
- }
- }
- }
-
-
-
- static void write_monoindex_span( GLuint n, GLint x, GLint y,
- const GLubyte mask[] )
- {
- GLubyte *ptr1 = (GLubyte *) Current->buffer + OFFSET(x,y);
- GLuint i;
- for (i=0;i<n;i++,ptr1++) {
- if (mask[i]) {
- *ptr1 = (GLubyte) Current->pixel;
- }
- }
- }
-
-
-
- static void write_index_pixels( GLuint n, const GLint x[], const GLint y[],
- const GLuint index[], const GLubyte mask[] )
- {
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLubyte *ptr1 = (GLubyte *) Current->buffer + OFFSET(x[i],y[i]);
- *ptr1 = (GLubyte) index[i];
- }
- }
- }
-
-
-
- static void write_monoindex_pixels( GLuint n, const GLint x[], const GLint y[],
- const GLubyte mask[] )
- {
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLubyte *ptr1 = (GLubyte *) Current->buffer + OFFSET(x[i],y[i]);
- *ptr1 = (GLubyte) Current->pixel;
- }
- }
- }
-
-
-
- static void read_index_span( GLuint n, GLint x, GLint y, GLuint index[] )
- {
- GLuint i;
- GLubyte *ptr1 = (GLubyte *) Current->buffer + OFFSET(x,y);
- for (i=0;i<n;i++,ptr1++) {
- index[i] = (GLuint) *ptr1;
- }
- }
-
-
- static void read_color_span( GLuint n, GLint x, GLint y,
- GLubyte red[], GLubyte green[],
- GLubyte blue[], GLubyte alpha[] )
- {
- GLuint i;
- GLubyte *ptr1 = (GLubyte *) Current->buffer + OFFSET(x,y) * 4;
- for (i=0;i<n;i++) {
- red[i] = *ptr1++;
- green[i] = *ptr1++;
- blue[i] = *ptr1++;
- alpha[i] = *ptr1++;
- }
- }
-
-
- static void read_index_pixels( GLuint n, const GLint x[], const GLint y[],
- GLuint index[], const GLubyte mask[] )
- {
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i] ) {
- GLubyte *ptr1 = (GLubyte *) Current->buffer + OFFSET(x[i],y[i]);
- index[i] = (GLuint) *ptr1;
- }
- }
- }
-
-
- static void read_color_pixels( GLuint n, const GLint x[], const GLint y[],
- GLubyte red[], GLubyte green[],
- GLubyte blue[], GLubyte alpha[],
- const GLubyte mask[] )
- {
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLubyte *ptr1 = (GLubyte *) Current->buffer + OFFSET(x[i],y[i]) * 4;
- red[i] = *ptr1++;
- green[i] = *ptr1++;
- blue[i] = *ptr1++;
- alpha[i] = *ptr1;
- }
- }
- }
-
-
- static points_func choose_points_function( void )
- {
- /* No accelerated points functions */
- return NULL;
- }
-
- static line_func choose_line_function( void )
- {
- /* No accelerated line functions */
- return NULL;
- }
-
- static polygon_func choose_polygon_function( void )
- {
- /* No accelerated polygon functions */
- return NULL;
- }
-
-
-
- static void setup_DD_pointers( void )
- {
- GLuint i4 = 1;
- GLubyte *i1 = (GLubyte *) &i4;
- GLint little_endian = *i1;
-
- DD.finish = finish;
- DD.flush = flush;
- DD.set_buffer = set_buffer;
- DD.color = set_color;
- DD.index = set_index;
- DD.clear_index = clear_index;
- DD.clear_color = clear_color;
- DD.clear = clear;
- DD.index_mask = index_mask;
- DD.color_mask = color_mask;
- DD.logicop = logicop;
- DD.dither = dither;
-
- DD.buffer_size = buffer_size;
-
- DD.get_points_func = choose_points_function;
- DD.get_line_func = choose_line_function;
- DD.get_polygon_func = choose_polygon_function;
-
- if (little_endian) {
- DD.write_color_span = write_ABGR_span;
- DD.write_color_pixels = write_ABGR_pixels;
- }
- else {
- DD.write_color_span = write_RGBA_span;
- DD.write_color_pixels = write_RGBA_pixels;
- }
- DD.write_index_span = write_index_span;
- DD.write_monocolor_span = write_monocolor_span;
- DD.write_monoindex_span = write_monoindex_span;
- DD.write_index_pixels = write_index_pixels;
- DD.write_monocolor_pixels = write_monocolor_pixels;
- DD.write_monoindex_pixels = write_monoindex_pixels;
-
- DD.read_color_span = read_color_span;
- DD.read_index_span = read_index_span;
- DD.read_color_pixels = read_color_pixels;
- DD.read_index_pixels = read_index_pixels;
- }
-